package com.shanhesoft.java.modules.sys.web;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.google.common.collect.Maps;
import com.shanhesoft.java.common.core.config.ApplicationConfig;
import com.shanhesoft.java.common.core.util.FileUploadUtil;
import com.shanhesoft.java.common.core.util.FileUtil;
import com.shanhesoft.java.common.core.util.Result;
import com.shanhesoft.java.common.core.util.StringUtil;

import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;

/**
 * 通用请求处理
 *
 * @author somewhere
 */
@Controller
@Slf4j
@RequestMapping("${application.admin-path}/file")
@Api(tags = "文件管理")
public class FileResource {


	/**
	 * 通用下载请求
	 *
	 * @param fileName 文件名称
	 * @param delete   是否删除
	 */
	@GetMapping("/download")
	public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) {
		try {
			if (!FileUtil.isValidFilename(fileName)) {
				throw new Exception(String.format("文件名称({})非法，不允许下载。 ", fileName));
			}
			String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
			String filePath = ApplicationConfig.getDownloadPath() + fileName;

			response.setCharacterEncoding("utf-8");
			response.setContentType("multipart/form-data");
			response.setHeader("Content-Disposition",
				"attachment;fileName=" + FileUtil.setFileDownloadHeader(request, realFileName));
			FileUtil.writeBytes(filePath, response.getOutputStream());
			if (delete) {
				FileUtil.deleteFile(filePath);
			}
		} catch (Exception e) {
			log.error("下载文件失败", e);
		}
	}

	/**
	 * 通用上传请求
	 */
	@PostMapping("/upload")
	@ResponseBody
	public Result uploadFile(MultipartFile file, HttpServletRequest request) throws IOException {
		//判断上传文件格式
        String fileType = file.getContentType();
        // 上传文件路径
        String filePath = "";
        if (fileType.equals("image/jpeg") || fileType.equals("image/png") || fileType.equals("image/gif")) {
        	filePath = ApplicationConfig.getImageFilePath();
        }else {
        	filePath = ApplicationConfig.getUploadPath();
        }
		// 上传并返回新文件名称
		String fileName = FileUploadUtil.upload(filePath, file);
		String url = getDomain(request) + fileName;
		HashMap<Object, Object> data = Maps.newHashMap();
		data.put("fileName", fileName);
		data.put("url", url);
		return Result.buildOkData(data);
	}
	
	/**
	 * 图片上传请求
	 */
	@PostMapping("/uploadImg")
	@ResponseBody
	public Result uploadImg(MultipartFile file, String imagePath, HttpServletRequest request) throws IOException {
		//判断上传文件格式
        String fileType = file.getContentType();
        // 上传文件路径
        String filePath = ApplicationConfig.getImageFilePath()+StringUtil.SLASH+imagePath;
		// 上传并返回新文件名称
		String fileName = FileUploadUtil.upload(filePath, file);
		String url = getDomain(request) + fileName;
		HashMap<Object, Object> data = Maps.newHashMap();
		data.put("fileName", fileName);
		data.put("url", url);
		return Result.buildOkData(data);
	}
	
	/**
	 * 图片预览
	 * @param fileName
	 * @param width
	 * @param height
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("imageView")
	public void imageView(String fileName, Integer width, Integer height,
			HttpServletRequest request, HttpServletResponse response)throws Exception  {
		if(width == null) {
			width = 0;
		}
		if(height == null) {
			height = 0;
		}
		int dirLastIndex = fileName.lastIndexOf(StringUtil.SLASH) + 1;
		byte[] data = FileUtil.readBytes(ApplicationConfig.getImageFilePath()+StringUtil.SLASH+StringUtil.subSuf(fileName, dirLastIndex));
		if (width != 0 && height != 0) {
			data = scaleImage(data, width, height);
		}
		response.setContentType("img/jpg");
		response.setCharacterEncoding("utf-8");
		try {
			OutputStream outputStream = response.getOutputStream();
			InputStream in = new ByteArrayInputStream(data);
			int len = 0;
			byte[] buf = new byte[1024];
			while ((len =in.read(buf,0,1024)) != -1) {
				outputStream.write(buf,0,len);
			}
			outputStream.close();
		} catch (IOException e){
			e.printStackTrace();
		}
	}

	private String getDomain(HttpServletRequest request) {
		StringBuffer url = request.getRequestURL();
		String contextPath = request.getServletContext().getContextPath();
		return url.delete(url.length() - request.getRequestURI().length(), url.length()).append(contextPath).toString();
	}
	

/**
	 * 调整报告图片大小
	 * @param data
	 * @param width
	 * @param height
	 * @return
	 * @throws IOException
	 */
	public  byte[] scaleImage(byte[] data, int width, int height) throws IOException {
		BufferedImage buffered_oldImage = ImageIO.read(new ByteArrayInputStream(data));
		int imageOldWidth = buffered_oldImage.getWidth();
		int imageOldHeight = buffered_oldImage.getHeight();
		double scale_x = (double) width / imageOldWidth;
		double scale_y = (double) height / imageOldHeight;
		double scale_xy = Math.min(scale_x, scale_y);
		int imageNewWidth = (int) (imageOldWidth * scale_xy);
		int imageNewHeight = (int) (imageOldHeight * scale_xy);
		BufferedImage buffered_newImage = new BufferedImage(imageNewWidth, imageNewHeight, BufferedImage.TYPE_INT_RGB);
		buffered_newImage.getGraphics().drawImage(buffered_oldImage.getScaledInstance(imageNewWidth, imageNewHeight, BufferedImage.SCALE_SMOOTH), 0, 0, null);
		buffered_newImage.getGraphics().dispose();
		ByteArrayOutputStream outPutStream = new ByteArrayOutputStream();
		ImageIO.write(buffered_newImage, "jpeg", outPutStream);
		return outPutStream.toByteArray();
	}
}
